home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 003 (1987-02-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 003 (1987-02-15)(Ossowski, Stefan)(DE)(PD).adf / BlackBook / blkbook.c < prev    next >
C/C++ Source or Header  |  1987-03-04  |  21KB  |  763 lines

  1. /*
  2.                   ------------------------------------
  3.                   *** Little Black Book © 1987 Lcc ***
  4.                   ------------------------------------
  5.  
  6.    This program is presented in the spirit of keeping shareware alive.
  7.  
  8.    You may freely copy and distribute, for non-commercial purposes, both
  9. Little Black Book and the limited file handler library (bfile.lib) provided
  10. that this documentation accompanies the programs and that no charge is made
  11. for copying and distribution.
  12.  
  13.    If you find these programs useful please send your contribution to the
  14. address below.  If you desire the full-blown bfile library on disk complete
  15. with source code (bfile is written in 'C' and is not Amiga specific) -
  16.  
  17.                 Please send the nominal fee of $30¹ to:
  18.  
  19.                           Craig Nelson
  20.                           Log Cabin Computer
  21.                           921 Arcola Ct PP
  22.                           Granbury, TX  76048
  23.  
  24.  ¹ A bona fide job offer may be substituted for cash as this programmer is
  25.    currently unemployed (817) 573-7304.
  26.  
  27.  
  28.                        Notes, caveats and stuff
  29.                       --------------------------
  30.  
  31.  * Because of special keyboard/mouse handling, runs only under WorkBench
  32.    release 1.2 (this does not apply to bfile.lib) 
  33.  
  34.  * Set up for 80 column because that's my preference
  35.  
  36.  * If the display flashes it's either your imagination or the beginning or
  37.    end of file has been reached
  38.  
  39.  * For the most part, either the keyboard or the mouse may be used
  40.    interchangeably - you'll get the idea just by playing around
  41.  
  42.    <Right Mouse>     move pointer to the bottom of window
  43.  
  44.    <RETURN>          when the pointer is at the bottom of window enters
  45.                      edit mode
  46.  
  47.    <CTRL><RETURN>    exits edit mode
  48.  
  49.    <Right AMIGA><Q>  restores a field
  50.  
  51.    <Right AMIGA><X>  clears a field
  52.  
  53.    <Right Cursor>    next record
  54.  
  55.    <Left Cursor>     previous record
  56.  
  57.    F1 - 'FND'        finds the first occurence > or = to entry typed
  58.                      (the record key is upper case so 'johnson' = 'JOHNSON')
  59.  
  60.    F2 - 'SAV'        saves changes made to an existing record
  61.  
  62.    F3 - 'ADD'        adds a new record
  63.  
  64.    F4 - 'DEL'        deletes a record
  65.  
  66.                                  - - -
  67. */
  68.  
  69. #include <intuition/intuition.h>
  70. #include <devices/input.h>
  71.  
  72. #define  BLUP  0
  73. #define  WHTP  1
  74. #define  BLKP  2
  75. #define  YLWP  3
  76.  
  77. #define  MESSAGE    (1 << wdw->UserPort->mp_SigBit)
  78. #define  IGNORE_MSG ((qual & 0x0200) || (code & 0x80)) /*  Key up, repeat */
  79. #define  ABORT_MSG   (qual & 0x2008)                   /*  CTRL, RMB      */
  80.  
  81. #define  FND_KEY  0x50     /*  F1           */
  82. #define  SAV_KEY  0x51     /*  F2           */
  83. #define  ADD_KEY  0x52     /*  F3           */
  84. #define  DEL_KEY  0x53     /*  F4           */
  85. #define  EDT_KEY  0x44     /*  Return       */
  86. #define  PRV_KEY  0x4F     /*  Left arrow   */
  87. #define  NXT_KEY  0x4E     /*  Right arrow  */
  88.  
  89. #define  NAM_GAD     1
  90. #define  ADR_GAD     2
  91. #define  CIT_GAD     3
  92. #define  STA_GAD     4
  93. #define  ZIP_GAD     5
  94. #define  PHN_GAD     6
  95. #define  NOT_GAD     7
  96. #define  FND_GAD     8
  97. #define  SAV_GAD     9
  98. #define  ADD_GAD    10
  99. #define  DEL_GAD    11
  100. #define  PRV_GAD    12
  101. #define  NXT_GAD    13
  102. #define  NEG_GAD    14
  103. #define  POS_GAD    15
  104.  
  105. #define  STR_GAD     7     /*  End of string gadgets  */
  106. #define  WDW_GAD    13     /*  End of normal gadgets  */
  107.  
  108. /*------------------------ Required by bfile.lib -------------------------*/
  109.  
  110. extern   int   BFILE_OK;
  111. typedef  char  BFILE[100];
  112.  
  113. /*----------------------- Database file definition -----------------------*/
  114.  
  115. #define  DUP   1          /*  Duplicate records OK  */
  116.  
  117. typedef  char  BKEY[26];  /*  Record key  */
  118.  
  119. struct DataRec {
  120.          char  Name[26],
  121.                Addr[26],
  122.                City[15],
  123.                State[3],
  124.                Zip[6],
  125.                Phone[15],
  126.                Note[81];
  127. } BookRec, SaveRec;
  128.  
  129.    BFILE       BookDataFile;
  130.    BFILE       BookIndexFile;
  131.    BKEY        BookKey;
  132.    int         BookRecNum;
  133.  
  134. /*---------------------- Special external functions ----------------------*/
  135.  
  136. extern struct MsgPort   *CreatePort();
  137. extern struct IOStdReq  *CreateStdIO();
  138. extern struct TextFont  *OpenFont();
  139.  
  140. /*----------------------------- Global data ------------------------------*/
  141.  
  142. struct IntuitionBase    *IntuitionBase;
  143. struct GfxBase          *GfxBase;
  144. struct Window           *wdw;
  145. struct IntuiMessage     *msg;
  146. struct RastPort         *rp;
  147. struct MsgPort          *dev;
  148. struct IOStdReq         *req;
  149. struct TextFont         *font;
  150.  
  151.    ULONG    class;
  152.    USHORT   code;
  153.    USHORT   qual;
  154.    APTR     iadr;
  155.    USHORT   gid;
  156.  
  157.    short    find_flag;
  158.  
  159.    char     Undo[81];
  160.    char     Note[26];
  161.    char     used[8];
  162.  
  163.    char
  164.       wdwttl[] = { " Little Black Book © 1987 Lcc " },
  165.       scrttl[] = { "Little Black Book © 1987 Lcc (817) 573-7304  WB 1.2 80 col" };
  166.  
  167. struct TextAttr
  168.    attr = { "topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT };
  169.  
  170. struct InputEvent
  171.    epos = { NULL, IECLASS_POINTERPOS, 0, IECODE_NOBUTTON, 0,0,0,0 },
  172.    ebut = { NULL, IECLASS_POINTERPOS, 0, IECODE_LBUTTON,  0,0,0,0 };
  173.  
  174.    USHORT   prv_pix[] = { 0xFE3F,0xF87F,0xC0FF,0x0000,0xC0FF,0xF87F,0xFE3F },
  175.             nxt_pix[] = { 0xFC7F,0xFE1F,0xFF03,0x0000,0xFF03,0xFE1F,0xFC7F };
  176.  
  177. struct Image
  178.    prv_img = { 4,0, 16,7,1, (USHORT *) &prv_pix, 0x2,0x0, NULL },
  179.    nxt_img = { 4,0, 16,7,1, (USHORT *) &nxt_pix, 0x2,0x0, NULL };
  180.  
  181.    SHORT    c03_pts[] = { -3,-1,   28,-1,   28,10,  -3,10,  -3,-1 },
  182.             c06_pts[] = { -3,-1,   52,-1,   52,10,  -3,10,  -3,-1 },
  183.             c15_pts[] = { -3,-1,  124,-1,  124,10,  -3,10,  -3,-1 },
  184.             c26_pts[] = { -3,-1,  212,-1,  212,10,  -3,10,  -3,-1 },
  185.             sel_pts[] = { -3,-1,   52,-1,   52, 9,  -3, 9,  -3,-1 };
  186.  
  187. struct Border
  188.    c03_brdr = { -1,-1, BLUP,BLKP,JAM1, 5,(SHORT *) &c03_pts, NULL },
  189.    c06_brdr = { -1,-1, BLUP,BLKP,JAM1, 5,(SHORT *) &c06_pts, NULL },
  190.    c15_brdr = { -1,-1, BLUP,BLKP,JAM1, 5,(SHORT *) &c15_pts, NULL },
  191.    c26_brdr = { -1,-1, BLUP,BLKP,JAM1, 5,(SHORT *) &c26_pts, NULL },
  192.    sel_brdr = { -1,-1, YLWP,BLKP,JAM1, 5,(SHORT *) &sel_pts, NULL },
  193.    neg_brdr = { -1,-1, BLKP,BLKP,JAM1, 5,(SHORT *) &c03_pts, NULL };
  194.  
  195. struct StringInfo
  196.    nam_info = { BookRec.Name , Undo, 0,26,0,0,0,0,0,0, NULL,0,NULL },
  197.    adr_info = { BookRec.Addr , Undo, 0,26,0,0,0,0,0,0, NULL,0,NULL },
  198.    cit_info = { BookRec.City , Undo, 0,15,0,0,0,0,0,0, NULL,0,NULL },
  199.    sta_info = { BookRec.State, Undo, 0, 3,0,0,0,0,0,0, NULL,0,NULL },
  200.    zip_info = { BookRec.Zip  , Undo, 0, 6,0,0,0,0,0,0, NULL,0,NULL },
  201.    phn_info = { BookRec.Phone, Undo, 0,15,0,0,0,0,0,0, NULL,0,NULL },
  202.    not_info = { BookRec.Note , Undo, 0,81,0,0,0,0,0,0, NULL,0,NULL };
  203.  
  204. struct IntuiText
  205.    nam_text = { BLUP,BLKP,JAM1, -44, 0,&attr, "Name"           , NULL      },
  206.    adr_text = { BLUP,BLKP,JAM1, -44, 0,&attr, "Addr"           , NULL      },
  207.    cit_text = { BLUP,BLKP,JAM1, -44, 0,&attr, "City"           , NULL      },
  208.    sta_text = { BLUP,BLKP,JAM1, -52, 0,&attr, "State"          , NULL      },
  209.    zip_text = { BLUP,BLKP,JAM1, -44, 0,&attr, "Zip"            , NULL      },
  210.    phn_text = { BLUP,BLKP,JAM1, -28, 0,&attr, "Ph"             , NULL      },
  211.    not_text = { BLUP,BLKP,JAM1, -44, 0,&attr, "Note"           , NULL      },
  212.    fnd_text = { BLUP,BLKP,JAM1,   0, 0,&attr, "F1=FND"         , NULL      },
  213.    sav_text = { BLUP,BLKP,JAM1,   0, 0,&attr, "F2=SAV"         , NULL      },
  214.    add_text = { BLUP,BLKP,JAM1,   0, 0,&attr, "F3=ADD"         , NULL      },
  215.    del_text = { BLUP,BLKP,JAM1,   0, 0,&attr, "F4=DEL"         , NULL      },
  216.    usd_text = { BLUP,BLKP,JAM2,   0, 0,&attr, used             , NULL      },
  217.  
  218.    neg_text = { BLKP,BLKP,JAM1,   4, 0,&attr, "No"             , NULL      },
  219.    pos_text = { BLKP,BLKP,JAM1,   0, 0,&attr, "Yes"            , NULL      },
  220.    avf_text = { BLKP,BLKP,JAM1,  48, 3,&attr, "Add Duplicate?" , NULL      },
  221.    dvf_text = { BLKP,BLKP,JAM1,  48, 3,&attr, "Delete Record?" , NULL      },
  222.    svf_text = { BLKP,BLKP,JAM1,  48, 3,&attr, "Changed - Save?", NULL      },
  223.  
  224.    not_disp = { WHTP,BLUP,JAM2,  56,71,&attr, Note             , NULL      },
  225.    phn_disp = { WHTP,BLUP,JAM2, 144,57,&attr, BookRec.Phone    , ¬_disp },
  226.    zip_disp = { WHTP,BLUP,JAM2,  56,57,&attr, BookRec.Zip      , &phn_disp },
  227.    sta_disp = { WHTP,BLUP,JAM2, 240,43,&attr, BookRec.State    , &zip_disp },
  228.    cit_disp = { WHTP,BLUP,JAM2,  56,43,&attr, BookRec.City     , &sta_disp },
  229.    adr_disp = { WHTP,BLUP,JAM2,  56,29,&attr, BookRec.Addr     , &cit_disp },
  230.    nam_disp = { WHTP,BLUP,JAM2,  56,15,&attr, BookRec.Name     , &adr_disp };
  231.  
  232. struct Gadget
  233.    nam_gdgt = { NULL, 56,15,208,8,  GADGHCOMP, RELVERIFY, STRGADGET,
  234.                 (APTR) &c26_brdr, NULL, &nam_text, 0, (APTR) &nam_info,
  235.                 NAM_GAD, NULL },
  236.  
  237.    adr_gdgt = { NULL, 56,29,208,8,  GADGHCOMP, RELVERIFY, STRGADGET,
  238.                 (APTR) &c26_brdr, NULL, &adr_text, 0, (APTR) &adr_info,
  239.                 ADR_GAD, NULL },
  240.  
  241.    cit_gdgt = { NULL, 56,43,120,8,  GADGHCOMP, RELVERIFY, STRGADGET,
  242.                 (APTR) &c15_brdr, NULL, &cit_text, 0, (APTR) &cit_info,
  243.                 CIT_GAD, NULL },
  244.  
  245.    sta_gdgt = { NULL, 240,43,24,8,  GADGHCOMP, RELVERIFY, STRGADGET,
  246.                 (APTR) &c03_brdr, NULL, &sta_text, 0, (APTR) &sta_info,
  247.                 STA_GAD, NULL },
  248.  
  249.    zip_gdgt = { NULL,  56,57,48,8,  GADGHCOMP, RELVERIFY, STRGADGET,
  250.                 (APTR) &c06_brdr, NULL, &zip_text, 0, (APTR) &zip_info,
  251.                 ZIP_GAD, NULL },
  252.  
  253.    phn_gdgt = { NULL,144,57,120,8,  GADGHCOMP, RELVERIFY, STRGADGET,
  254.                 (APTR) &c15_brdr, NULL, &phn_text, 0, (APTR) &phn_info,
  255.                 PHN_GAD, NULL },
  256.  
  257.    not_gdgt = { NULL, 56,71,208,8,  GADGHCOMP, RELVERIFY, STRGADGET,
  258.                 (APTR) &c26_brdr, NULL, ¬_text, 0, (APTR) ¬_info,
  259.                 NOT_GAD, NULL },
  260.  
  261.    fnd_gdgt = { NULL,  15,87,48,7,  GADGHCOMP, RELVERIFY, BOOLGADGET,
  262.                 (APTR) &sel_brdr, NULL, &fnd_text, 0, (APTR) NULL,
  263.                 FND_GAD, NULL },
  264.  
  265.    sav_gdgt = { NULL,  76,87,48,7,  GADGHCOMP, RELVERIFY, BOOLGADGET,
  266.                 (APTR) &sel_brdr, NULL, &sav_text, 0, (APTR) NULL,
  267.                 SAV_GAD, NULL },
  268.  
  269.    add_gdgt = { NULL, 137,87,48,7,  GADGHCOMP, RELVERIFY, BOOLGADGET,
  270.                 (APTR) &sel_brdr, NULL, &add_text, 0, (APTR) NULL,
  271.                 ADD_GAD, NULL },
  272.  
  273.    del_gdgt = { NULL, 198,87,48,7,  GADGHCOMP, RELVERIFY, BOOLGADGET,
  274.                 (APTR) &sel_brdr, NULL, &del_text, 0, (APTR) NULL,
  275.                 DEL_GAD, NULL },
  276.  
  277.    prv_gdgt = { NULL, 259,87,24,7,  GADGIMAGE | GADGHCOMP,
  278.                 RELVERIFY, BOOLGADGET,
  279.                 (APTR) &prv_img,  NULL, NULL,      0, (APTR) NULL,
  280.                 PRV_GAD, NULL },
  281.  
  282.    nxt_gdgt = { NULL, 283,87,24,7,  GADGIMAGE | GADGHCOMP,
  283.                 RELVERIFY, BOOLGADGET,
  284.                 (APTR) &nxt_img,  NULL, NULL,      0, (APTR) NULL,
  285.                 NXT_GAD, NULL },
  286.  
  287.    neg_gdgt = { NULL,      222,3,24,8, GADGHNONE,
  288.                 RAWKEY | TOGGLESELECT | ENDGADGET, BOOLGADGET | REQGADGET,
  289.                 (APTR) &neg_brdr, NULL, &neg_text, 0, (APTR) NULL,
  290.                 NEG_GAD, NULL },
  291.  
  292.    pos_gdgt = { &neg_gdgt, 182,3,24,8, GADGHNONE,
  293.                 RAWKEY | TOGGLESELECT | ENDGADGET, BOOLGADGET | REQGADGET,
  294.                 (APTR) &neg_brdr, NULL, &pos_text, 0, (APTR) NULL,
  295.                 POS_GAD, NULL };
  296.  
  297. struct Requester
  298.    vfy_rqst = { NULL, 11,83,299,14, 0,0, &pos_gdgt, NULL, NULL, 0, YLWP,
  299.                 NULL, NULL, NULL, NULL, NULL };
  300.  
  301. struct NewWindow
  302.    NewWdw = { 160,11,320,100,  BLKP,WHTP,
  303.               CLOSEWINDOW   | GADGETUP   | RAWKEY      | MOUSEBUTTONS,
  304.               WINDOWCLOSE   | WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH |
  305.               NOCAREREFRESH | RMBTRAP    | ACTIVATE,
  306.               NULL, NULL, NULL, NULL, NULL, 0,0,0,0, WBENCHSCREEN };
  307.  
  308. /*----------------------------- Main program -----------------------------*/
  309.  
  310. _main()
  311. {
  312.    init();
  313.  
  314.    StartKey(&BookIndexFile);
  315.    next();
  316.  
  317.    moveptr(&nxt_gdgt,0);
  318.  
  319.    while (TRUE) {
  320.  
  321.       Wait(MESSAGE);
  322.  
  323.       while (msg = (struct IntuiMessage *) GetMsg(wdw->UserPort))  {
  324.          class = msg->Class;
  325.          code  = msg->Code;
  326.          qual  = msg->Qualifier;
  327.          iadr  = msg->IAddress;
  328.  
  329.          ReplyMsg(msg);
  330.  
  331.          if (class == GADGETUP)
  332.             gid = ((struct Gadget *) iadr)->GadgetID;
  333.          else
  334.             gid = 0;
  335.  
  336.          if (!IGNORE_MSG) {
  337.  
  338.             if ((find_flag) && (gid != NAM_GAD))
  339.                kill_find();
  340.  
  341.             if (ABORT_MSG) {
  342.                moveptr(&nxt_gdgt,0);
  343.             } else {
  344.                switch (class) {
  345.                   case GADGETUP:
  346.                      dispatch_gad();
  347.                      break;
  348.                   case RAWKEY:
  349.                      dispatch_key();
  350.                      break;
  351.                   case CLOSEWINDOW:
  352.                      quit(0);
  353.                      break;
  354.                }
  355.             }
  356.          }
  357.       }
  358.    }
  359. }
  360.  
  361. /*--------------------------- Function dispatch --------------------------*/
  362.  
  363. dispatch_gad()
  364. {
  365.    switch (gid) {
  366.       case FND_GAD:
  367.          set_find();
  368.          break;
  369.       case ADD_GAD:
  370.          add();
  371.          break;
  372.       case SAV_GAD:
  373.          save();
  374.          break;
  375.       case DEL_GAD:
  376.          delete();
  377.          break;
  378.       case PRV_GAD:
  379.          prev();
  380.          break;
  381.       case NXT_GAD:
  382.          next();
  383.          break;
  384.       case NAM_GAD:
  385.          if (find_flag)
  386.             find();
  387.          else
  388.             moveptr(&adr_gdgt,1);
  389.          break;
  390.       case ADR_GAD:
  391.          moveptr(&cit_gdgt,1);
  392.          break;
  393.       case CIT_GAD:
  394.          moveptr(&sta_gdgt,1);
  395.          break;
  396.       case STA_GAD:
  397.          moveptr(&zip_gdgt,1);
  398.          break;
  399.       case ZIP_GAD:
  400.          moveptr(&phn_gdgt,1);
  401.          break;
  402.       case PHN_GAD:
  403.          moveptr(¬_gdgt,1);
  404.          break;
  405.       case NOT_GAD:
  406.          moveptr(&nxt_gdgt,0);
  407.          break;
  408.    }
  409. }
  410.  
  411. dispatch_key()
  412. {
  413.    switch (code) {
  414.       case FND_KEY:
  415.          set_find();
  416.          break;
  417.       case SAV_KEY:
  418.          moveptr(&sav_gdgt,0);
  419.          save();
  420.          break;
  421.       case ADD_KEY:
  422.          moveptr(&add_gdgt,0);
  423.          add();
  424.          break;
  425.       case DEL_KEY:
  426.          moveptr(&del_gdgt,0);
  427.          delete();
  428.          break;
  429.       case PRV_KEY:
  430.          moveptr(&prv_gdgt,0);
  431.          prev();
  432.          break;
  433.       case NXT_KEY:
  434.          moveptr(&nxt_gdgt,0);
  435.          next();
  436.          break;
  437.       case EDT_KEY:
  438.          moveptr(&nam_gdgt,1);
  439.          break;
  440.    }
  441. }
  442.  
  443. /*--------------------------- Function handlers --------------------------*/
  444.  
  445. set_find()
  446. {
  447.    if (UsedRecs(&BookDataFile)) {
  448.       chkrec();
  449.       setmem(&BookRec,sizeof(BookRec),'\0');
  450.       showrec();
  451.       find_flag = TRUE;
  452.       moveptr(&nam_gdgt,1);
  453.    }
  454. }
  455.  
  456. find()
  457. {
  458.    if (strlen(BookRec.Name)) {
  459.       genkey(BookRec.Name,BookKey,sizeof(BKEY));
  460.       SearchKey(&BookIndexFile,&BookRecNum,BookKey);
  461.       if (!BFILE_OK)
  462.          PrevKey(&BookIndexFile,&BookRecNum,BookKey);
  463.       readrec();
  464.    } else {
  465.       kill_find();
  466.    }
  467.    moveptr(&fnd_gdgt,0);
  468. }
  469.  
  470. kill_find()
  471. {
  472.    BookRec = SaveRec;
  473.    showrec();
  474.    find_flag = FALSE;
  475. }
  476.  
  477. save()
  478. {
  479.    BKEY  tmpkey;
  480.  
  481.    if (UsedRecs(&BookDataFile)) {
  482.       PutRec(&BookDataFile,BookRecNum,&BookRec);
  483.       genkey(SaveRec.Name,tmpkey,sizeof(BKEY));
  484.       genkey(BookRec.Name,BookKey,sizeof(BKEY));
  485.       if (strncmp(tmpkey,BookKey,sizeof(BKEY))) {
  486.          DeleteKey(&BookIndexFile,&BookRecNum,tmpkey);
  487.          AddKey(&BookIndexFile,BookRecNum,BookKey);
  488.          FindKey(&BookIndexFile,&BookRecNum,BookKey);
  489.       }
  490.       SaveRec = BookRec;
  491.    }
  492. }
  493.  
  494. add()
  495. {
  496.    if (strlen(BookRec.Name)) {
  497.       genkey(BookRec.Name,BookKey,sizeof(BKEY));
  498.       FindKey(&BookIndexFile,&BookRecNum,BookKey);
  499.       if (BFILE_OK)
  500.          BFILE_OK = !verify(&avf_text);
  501.       if (!BFILE_OK) {
  502.          AddRec(&BookDataFile,&BookRecNum,&BookRec);
  503.          genkey(BookRec.Name,BookKey,sizeof(BKEY));
  504.          AddKey(&BookIndexFile,BookRecNum,BookKey);
  505.          FindKey(&BookIndexFile,&BookRecNum,BookKey);
  506.          showusd();
  507.       }
  508.       SaveRec = BookRec;
  509.    }
  510. }
  511.  
  512. delete()
  513. {
  514.    if (UsedRecs(&BookDataFile)) {
  515.       if (verify(&dvf_text)) {
  516.          DeleteKey(&BookIndexFile,&BookRecNum,BookKey);
  517.          DeleteRec(&BookDataFile,BookRecNum);
  518.          SearchKey(&BookIndexFile,&BookRecNum,BookKey);
  519.          if (!BFILE_OK)
  520.             PrevKey(&BookIndexFile,&BookRecNum,BookKey);
  521.          showusd();
  522.          readrec();
  523.       }
  524.    }
  525. }
  526.  
  527. next()
  528. {
  529.    if (UsedRecs(&BookDataFile)) {
  530.       chkrec();
  531.       NextKey(&BookIndexFile,&BookRecNum,BookKey);
  532.       if (!BFILE_OK) {
  533.          DisplayBeep(NULL);
  534.          PrevKey(&BookIndexFile,&BookRecNum,BookKey);
  535.       }
  536.       readrec();
  537.    }
  538. }
  539.  
  540. prev()
  541. {
  542.    if (UsedRecs(&BookDataFile)) {
  543.       chkrec();
  544.       PrevKey(&BookIndexFile,&BookRecNum,BookKey);
  545.       if (!BFILE_OK) {
  546.          DisplayBeep(NULL);
  547.          NextKey(&BookIndexFile,&BookRecNum,BookKey);
  548.       }
  549.       readrec();
  550.    }
  551. }
  552.  
  553. /*---------------------------- Initialization ----------------------------*/
  554.  
  555. init()
  556. {
  557.    struct Gadget  *p;
  558.    int             x1,y1,x2,y2;
  559.    register int    i;
  560.  
  561.    if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0)))
  562.       quit(-1);
  563.  
  564.    if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0)))
  565.       quit(-2);
  566.  
  567.    if (!(dev = CreatePort(0,0)))
  568.       quit(-3);
  569.  
  570.    if (!(req = CreateStdIO(dev)))
  571.       quit(-4);
  572.  
  573.    if (OpenDevice("input.device",0,req,0))
  574.       quit(-5);
  575.  
  576.    req->io_Command = IND_WRITEEVENT;
  577.    req->io_Flags   = 0;
  578.    req->io_Length  = sizeof(struct InputEvent);
  579.  
  580.    OpenFile(&BookDataFile,"BLKBOOK.DAT",sizeof(BookRec));
  581.    if (BFILE_OK)
  582.       OpenIndex(&BookIndexFile,"BLKBOOK.IDX",sizeof(BKEY),DUP);
  583.    if (!BFILE_OK) {
  584.       MakeFile(&BookDataFile,"BLKBOOK.DAT",sizeof(BookRec));
  585.       if (BFILE_OK)
  586.          MakeIndex(&BookIndexFile,"BLKBOOK.IDX",sizeof(BKEY),DUP);
  587.    }
  588.  
  589.    if (!BFILE_OK)
  590.       quit(-6);
  591.  
  592.    if (!(wdw = (struct Window *) OpenWindow(&NewWdw)))
  593.       quit(-7);
  594.  
  595.    rp = wdw->RPort;
  596.  
  597.    if (font = OpenFont(&attr))
  598.       SetFont(rp,font);
  599.  
  600.    SetWindowTitles(wdw,wdwttl,scrttl);
  601.  
  602.    SetAPen(rp,BLKP);
  603.    RectFill(rp,1,10,318,98);
  604.  
  605.    DrawBorder(rp,&sel_brdr,258,87);
  606.  
  607.    SetAPen(rp,BLUP);
  608.    for (i = 1, p = &nam_gdgt; i <= WDW_GAD; i++, p++) {
  609.       if (p->GadgetID <= STR_GAD) {
  610.          x1 = p->LeftEdge;
  611.          y1 = p->TopEdge;
  612.          x2 = x1 + p->Width - 1;
  613.          y2 = y1 + p->Height - 1;
  614.          RectFill(rp,x1,y1,x2,y2);
  615.       }
  616.       AddGadget(wdw,p,-1);
  617.    }
  618.  
  619.    SetAPen(rp,WHTP);
  620.  
  621.    RefreshGadgets(wdw->FirstGadget,wdw,NULL);
  622.  
  623.    showusd();
  624. }
  625.  
  626. /*---------------------------- Misc functions ----------------------------*/
  627.  
  628. readrec()
  629. {
  630.    GetRec(&BookDataFile,BookRecNum,&BookRec);
  631.    showrec();
  632.    genkey(BookRec.Name,BookKey,sizeof(BKEY));
  633.    SaveRec = BookRec;
  634. }
  635.  
  636. showrec()
  637. {
  638.    struct StringInfo  *p;
  639.    register int        i;
  640.  
  641.    for (i = 1, p = &nam_info; i <= STR_GAD; i++, p++)
  642.       pad(p->Buffer,p->MaxChars);
  643.  
  644.    strncpy(Note,BookRec.Note,sizeof(Note));
  645.  
  646.    PrintIText(rp,&nam_disp,0,0);
  647.  
  648.    for (i = 1, p = &nam_info; i <= STR_GAD; i++, p++)
  649.       p->NumChars = trim(p->Buffer);
  650. }
  651.  
  652. pad(str,len)
  653.    char  *str;
  654.    int    len;
  655. {
  656.    setmem(&str[strlen(str)],len - strlen(str),' ');
  657.    str[len - 1] = '\0';
  658. }
  659.  
  660. trim(str)
  661.    char  *str;
  662. {
  663.    register int  i;
  664.  
  665.    for (i = strlen(str) - 1; (i >= 0) && (str[i] == ' '); str[i--] = '\0');
  666.    return(++i);
  667. }
  668.  
  669. showusd()
  670. {
  671.    sprintf(used,"%5d",UsedRecs(&BookDataFile));
  672.    PrintIText(rp,&usd_text,270,15);
  673. }
  674.  
  675. genkey(src,dst,len)
  676.    char  *src;
  677.    char  *dst;
  678.    int    len;
  679. {
  680.    while (len--)
  681.       (*src) ? (*dst++ = toupper(*src++)) : (*dst++ = ' ');
  682. }
  683.  
  684. chkrec()
  685. {
  686.       if (strcmp(BookRec.Name ,SaveRec.Name ) ||
  687.           strcmp(BookRec.Addr ,SaveRec.Addr ) ||
  688.           strcmp(BookRec.City ,SaveRec.City ) ||
  689.           strcmp(BookRec.State,SaveRec.State) ||
  690.           strcmp(BookRec.Zip  ,SaveRec.Zip  ) ||
  691.           strcmp(BookRec.Phone,SaveRec.Phone) ||
  692.           strcmp(BookRec.Note ,SaveRec.Note ))
  693.             if (verify(&svf_text))
  694.                save();
  695. }
  696.  
  697. moveptr(gad,butn)
  698.    struct Gadget *gad;
  699.    int            butn;
  700. {
  701.    epos.ie_X = ebut.ie_X =
  702.       wdw->LeftEdge + gad->LeftEdge + gad->Width - 2;
  703.    epos.ie_Y = ebut.ie_Y =
  704.       (wdw->TopEdge + gad->TopEdge + gad->Height - 1) << 1;
  705.  
  706.    if (butn)
  707.       req->io_Data = (APTR) &ebut;
  708.    else
  709.       req->io_Data = (APTR) &epos;
  710.  
  711.    DoIO(req);
  712. }
  713.  
  714. verify(txt)
  715.    struct IntuiText  *txt;
  716. {
  717.    vfy_rqst.ReqText = txt;
  718.    pos_gdgt.Flags &= ~SELECTED;
  719.    neg_gdgt.Flags &= ~SELECTED;
  720.  
  721.    Request(&vfy_rqst,wdw);
  722.  
  723.    Wait(MESSAGE);
  724.    msg = (struct IntuiMessage *) GetMsg(wdw->UserPort);
  725.    ReplyMsg(msg);
  726.  
  727.    return((int) pos_gdgt.Flags & SELECTED);
  728. }
  729.  
  730. /*----------------------------- Termination ------------------------------*/
  731.  
  732. quit(err)
  733.    int   err;
  734. {
  735.    CloseFile(&BookDataFile);
  736.    CloseIndex(&BookIndexFile);
  737.  
  738.    if (req) {
  739.       CloseDevice(req);
  740.       DeleteStdIO(req);
  741.    }
  742.  
  743.    if (dev)
  744.       DeletePort(dev);
  745.  
  746.    if (font)
  747.       CloseFont(font);
  748.  
  749.    if (wdw)
  750.       CloseWindow(wdw);
  751.  
  752.    if (GfxBase)
  753.       CloseLibrary(GfxBase);
  754.  
  755.    if (IntuitionBase)
  756.       CloseLibrary(IntuitionBase);
  757.  
  758.    OpenWorkBench();
  759.  
  760.    exit(err);
  761. }
  762.  
  763.